package com.choudou5.solr.service;

import cn.hutool.core.collection.CollUtil;
import com.choudou5.nlp.service.IAnalysisService;
import com.choudou5.nlp.util.BosonUtil;
import com.choudou5.nlp.util.PullWordUtil;
import com.choudou5.nlp.util.SogouUtil;
import com.choudou5.solr.annotation.ServiceInfo;
import com.choudou5.solr.bean.DicExtWords;
import com.choudou5.solr.framework.constants.SysConsts;
import com.choudou5.solr.framework.constants.UserConsts;
import com.choudou5.solr.framework.util.UserUtil;
import com.choudou5.solr.util.*;
import com.choudou5.solr.util.bean.WordBean;
import com.choudou5.solr.util.exception.BizException;
import com.choudou5.solr.util.thread.ThreadUtil;
import com.choudou5.solr.utils.SqlQueryBuilder;
import org.wltea.analyzer.dic.Dictionary;

import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * @name 扩展词库 接口
 * @author choudou5
 * @date 2018-7-13
 */
@ServiceInfo(table = "solr_dic_ext_words", desc = "扩展词库")
public class DicExtWordsService extends BaseService<DicExtWords> implements IAnalysisService {

    public void add(String keyword) throws BizException {
        DicExtWords dicExtWords = new DicExtWords(keyword);
        super.add(dicExtWords);
    }

    public void imporWords(Collection<String> list) throws BizException {
        if(CollUtil.isEmpty(list))
            return;
        AssertUtil.isTrue(StrUtil.isUTF8(list.iterator().next()), "导入失败，非UTF8 编码内容");
        //加载到词库
        Set<String> succWordList = Dictionary.getSingleton().addExtDict(list);
        //加入到数据库
        if(!succWordList.isEmpty()){
            LogDeBugUtil.debug("成功加入词库 " + succWordList.size() + "条");
            int version = DateUtil.getIntMs();
            int dex = 1;
            StringBuilder sql = new StringBuilder();
            sql.append("INSERT INTO "+getTable()+" (`id`,`word`,`create_by`,`create_time`,`version`) VALUES");
            Integer createBy = UserUtil.getUserId();
            if(createBy == null)
                createBy = UserConsts.SYS_USER_ID;
            for (String word : list) {
                if(!SqlQueryBuilder.isIncludeSqlInject(word) && word.length() < 10){
                    sql.append((dex>1?", ":"") + "("+SysSeqUtil.genTimeId(dex)+", '"+word+"', "+createBy+", '"+ DateUtil.now()+"', "+version+")");
                    dex++;
                }
            }
            if(dex > 1){
                sql.append(" ON DUPLICATE KEY UPDATE `word` = VALUES(`word`);");
                LogDeBugUtil.debug(sql.toString());
                batchAdd(sql.toString());
                addSynDynamic(SysConsts.ActionType.ADD, "导入了一批词库");
            }
        }
    }

    private Queue<String> queue = new ArrayBlockingQueue(1000);
    private volatile long lastTimestamp = -1;

    @Override
    public void textDefAnalysis(String text) {
        if(StrUtil.isBlank(text) || text.equals("*:*"))
            return;
        long timestamp = System.currentTimeMillis();
        queue.add(text);
        if((timestamp - lastTimestamp) > 3000){
            //批量取出语句
            int index = 0;
            final StringBuffer textStr = new StringBuffer(36);
            String txt = null;
            while(index < 10 && (txt = queue.poll()) != null){
                if(index > 0)
                    textStr.append(",");
                textStr.append(txt);
                index++;
            }

            //批量执行分析
            ThreadUtil.execAsync(new Runnable() {
                @Override
                public void run() {
                    try {
                        LogDeBugUtil.debug("分析文本：", textStr.toString());
                        Set<WordBean> wordList = PullWordUtil.getTextAnalysis(textStr.toString());
                        if (CollUtil.isNotEmpty(wordList)) {
                            batchAddWordBean(wordList);
                        } else {
                            wordList = SogouUtil.getTextAnalysis(textStr.toString());
                            if (CollUtil.isNotEmpty(wordList)) {
                                batchAddWordBean(wordList);
                            } else {
                                textBosonAnalysis(textStr.toString());
                            }
                        }
                    } catch (BizException e) {
                        logger.error("分析词性失败", e);
                    }
                }
            });
        }
        lastTimestamp = timestamp;
    }


    public void textBosonAnalysis(String text) {
        Set<WordBean> wordList = BosonUtil.getTextAnalysis(text);
        if(CollUtil.isNotEmpty(wordList)){
            batchAddWordBean(wordList);
        }
    }

    public void batchAddWordBean(Set<WordBean> list) throws BizException {
        //加载到词库
        List<WordBean> succWordList = Dictionary.getSingleton().addExtWordDict(list);
        //加入到数据库
        if(!succWordList.isEmpty()){
            LogDeBugUtil.debug("成功加入词库 " + succWordList.size() + "条");
            long version = DateUtil.getUnixTimeStamp();
            int dex = 1;
            StringBuilder sql = new StringBuilder();
            sql.append("INSERT INTO " + getTable() + " (`id`,`word`,`type`,`create_time`,`version`) VALUES");
            for (WordBean bean : list) {
                sql.append((dex>1?", ":"") + "("+ SysSeqUtil.generateId()+", \""+bean.getWord()+"\", '"+bean.getType()+"', '"+ DateUtil.now()+"', "+version+")");
                dex++;
            }
            if(dex > 1){
                sql.append(" ON DUPLICATE KEY UPDATE `word` = VALUES(`word`);");
                LogDeBugUtil.debug(sql.toString());
                batchAdd(sql.toString());
            }
        }
    }

    public void batchInsertWordBean(Set<WordBean> list) throws BizException {
        //加载到词库
        //加入到数据库
        if(CollUtil.isNotEmpty(list)){
            long version = DateUtil.getUnixTimeStamp();
            int dex = 1;
            StringBuilder sql = new StringBuilder();
            sql.append("INSERT INTO " + getTable() + " (`id`,`word`,`type`,`create_time`,`version`) VALUES");
            for (WordBean bean : list) {
                sql.append((dex>1?", ":"") + "("+ SysSeqUtil.generateId()+", \""+bean.getWord()+"\", '"+bean.getType()+"', '"+ DateUtil.now()+"', "+version+")");
                dex++;
            }
            if(dex > 1){
                sql.append(" ON DUPLICATE KEY UPDATE `word` = VALUES(`word`);");
                LogDeBugUtil.debug(sql.toString());
                batchAdd(sql.toString());
            }
        }
    }


}
